package testdomainsupermarket;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Collection;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import conditionsAPI.AndDomainCondition;
import conditionsAPI.ConditionDuplicatedException;
import conditionsAPI.ConditionsConfiguration;

public class TestDomainSupermarket {

	private FriesPackagesCondition friesCondition;
	private SodasSameBrandCondition sodasCondition;
	private PerfumeryItemCondition perfumeryCondition;
	
	private AndDomainCondition andCondition;
	
	private final int EXPECTED_NUM_SODAS = 2;
	private final int EXPECTED_FRIES_PACKAGES = 1;
	
	@Before
	public void setUp(){
		try {
			this.friesCondition = new FriesPackagesCondition("fries");
			this.friesCondition.setExpectedFriesPackages(this.EXPECTED_FRIES_PACKAGES);
			
			this.sodasCondition = new SodasSameBrandCondition("sodas");
			this.sodasCondition.setExpectedNumSodas(this.EXPECTED_NUM_SODAS);
			
			this.perfumeryCondition =  new PerfumeryItemCondition("perfumery");
			
			this.andCondition = new AndDomainCondition("and");
		} catch (ConditionDuplicatedException e) {
			e.printStackTrace();
		}
		
		this.andCondition.addPreCondition(this.friesCondition);
		this.andCondition.addPreCondition(this.sodasCondition);
		this.andCondition.addPreCondition(this.perfumeryCondition);
	}
	
	@After
	public void tearDown(){
		ConditionsConfiguration.reset();
	}
	
	@Test
	public void setTargetAndConditionSomeConditionsFulfilledCheckTargetResultEqualsPerfumery(){
		ConditionsConfiguration.setTarget(this.andCondition);
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.PEPSI));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.processObjects(lineItems);
		
		assertEquals(this.perfumeryCondition.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}
	
	@Test
	public void setTargetAndConditionSomeConditionsFulfilledCheckAndConditionIsFalse(){
		ConditionsConfiguration.setTarget(this.andCondition);
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.PEPSI));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.processObjects(lineItems);
		
		assertFalse(this.andCondition.isTrue());
	}
	
	@Test
	public void setTargetAndConditionAllConditionsFulfilledCheckTargetResultEqualsAndCondition(){
		ConditionsConfiguration.setTarget(this.andCondition);
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.processObjects(lineItems);
		
		assertEquals(this.andCondition.getId(),ConditionsConfiguration.getLastConditionFulfilled());
	}	
	
	@Test
	public void setTargetAndConditionAllConditionsFulfilledCheckAndConditionIsTrue(){
		ConditionsConfiguration.setTarget(this.andCondition);
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.processObjects(lineItems);
		
		assertTrue(this.andCondition.isTrue());
	}
	
	@Test
	public void testSameTargetWithDiferentCollectionsSecuential(){
		
		this.andCondition.enableConditionOrder();
		ConditionsConfiguration.setTarget(this.andCondition);
		
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.processObjects(lineItems);
		assertTrue(this.andCondition.isTrue());
		
		Collection<Object> lineItems2 = new ArrayList<Object>();
		
		ConditionsConfiguration.resetConditions();
		ConditionsConfiguration.processObjects(lineItems2);
		assertFalse(this.andCondition.isTrue());
		
		Collection<Object> lineItems3 = new ArrayList<Object>();
		lineItems3.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.PEPSI));
		lineItems3.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.PEPSI));
		lineItems3.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems3.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		
		ConditionsConfiguration.resetConditions();
		ConditionsConfiguration.processObjects(lineItems3);
		assertTrue(this.andCondition.isTrue());
	}
	
	@Test
	public void testAllItemsButSodasInWrongOrderOrderEnabled(){
		this.andCondition.enableConditionOrder();
		ConditionsConfiguration.setTarget(this.andCondition);
		Collection<Object> lineItems = new ArrayList<Object>();
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.PEPSI));
		lineItems.add(new LineItem(LineItem.Categories.FRIES,LineItem.BrandNames.LAYS));
		lineItems.add(new LineItem(LineItem.Categories.PERFUMERY,LineItem.BrandNames.LUX));
		lineItems.add(new LineItem(LineItem.Categories.SODA,LineItem.BrandNames.COCACOLA));
		
		ConditionsConfiguration.processObjects(lineItems);
		
		assertFalse(this.andCondition.isTrue());
	}
}
